# Copyright (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

from __future__ import annotations

import json

import pytest

from ansible.module_utils.common.text.converters import to_text
from ansible_collections.community.general.plugins.modules import nmcli
from ansible.module_utils.basic import AnsibleModule  # noqa: F401 # pylint: disable=unused-import

pytestmark = pytest.mark.usefixtures("patch_ansible_module")

TESTCASE_CONNECTION = [
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "generic",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "team",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "bond",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "bond-slave",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "bridge",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "vlan",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "vxlan",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "gre",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "ipip",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "sit",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "dummy",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "gsm",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "wireguard",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "vpn",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "infiniband",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "macvlan",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
    {
        "type": "loopback",
        "conn_name": "non_existent_nw_device",
        "state": "absent",
        "_ansible_check_mode": True,
    },
]

TESTCASE_GENERIC = [
    {
        "type": "generic",
        "conn_name": "non_existent_nw_device",
        "ifname": "generic_non_existant",
        "ip4": "10.10.10.10/24",
        "gw4": "10.10.10.1",
        "state": "present",
        "_ansible_check_mode": False,
    },
]

TESTCASE_GENERIC_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              generic_non_existant
connection.autoconnect:                 yes
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/24
ipv4.gateway:                           10.10.10.1
ipv4.route-metric:                      -1
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
"""

TESTCASE_GENERIC_DIFF_CHECK = [
    {
        "type": "generic",
        "conn_name": "non_existent_nw_device",
        "ifname": "generic_non_existant",
        "ip4": "10.10.10.10/24",
        "gw4": "10.10.10.2",
        "route_metric4": -1,
        "state": "present",
        "_ansible_check_mode": False,
    },
]

TESTCASE_GENERIC_MODIFY_ROUTING_RULES = [
    {
        "type": "generic",
        "conn_name": "non_existent_nw_device",
        "ifname": "generic_non_existant",
        "ip4": "10.10.10.10/24",
        "gw4": "10.10.10.1",
        "routing_rules4": ["priority 5 from 10.0.0.0/24 table 5000", "priority 10 from 10.0.1.0/24 table 5001"],
        "state": "present",
        "_ansible_check_mode": False,
    },
]

TESTCASE_GENERIC_MODIFY_ROUTING_RULES_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              generic_non_existant
connection.autoconnect:                 yes
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/24
ipv4.gateway:                           10.10.10.1
ipv4.routing-rules:                     priority 5 from 10.0.0.0/24 table 5000, priority 10 from 10.0.1.0/24 table 5001
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
"""

TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_ROUTE = [
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "ifname": "ethernet_non_existant",
        "ip6": "2001:beef:cafe:10::1/64",
        "routes6": ["fd2e:446f:d85d:5::/64 2001:beef:cafe:10::2"],
        "method6": "manual",
        "state": "present",
        "_ansible_check_mode": False,
    },
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "ifname": "ethernet_non_existant",
        "ip6": "2001:beef:cafe:10::1/64",
        "routes6_extended": [{"ip": "fd2e:446f:d85d:5::/64", "next_hop": "2001:beef:cafe:10::2"}],
        "method6": "manual",
        "state": "present",
        "_ansible_check_mode": False,
    },
]

TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_ROUTE_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              ethernet_non_existant
connection.autoconnect:                 yes
ipv4.method:                            auto
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            manual
ipv6.addresses:                         2001:beef:cafe:10::1/64
ipv6.routes:                            { ip = fd2e:446f:d85d:5::/64, nh = 2001:beef:cafe:10::2 }
ipv6.route-metric:                      -1
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
"""

TESTCASE_ETHERNET_MOD_IPV4_INT_WITH_ROUTE_AND_METRIC = [
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "routes4": ["192.168.200.0/24 192.168.1.1"],
        "route_metric4": 10,
        "state": "present",
        "_ansible_check_mode": False,
    },
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "routes4_extended": [{"ip": "192.168.200.0/24", "next_hop": "192.168.1.1"}],
        "route_metric4": 10,
        "state": "present",
        "_ansible_check_mode": False,
    },
]

TESTCASE_ETHERNET_MOD_IPV4_INT_WITH_ROUTE_AND_METRIC_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              ethernet_non_existant
connection.autoconnect:                 yes
ipv4.method:                            manual
ipv4.addresses:                         192.168.1.10
ipv4.routes:                            { ip = 192.168.200.0/24, nh = 192.168.1.1 }
ipv4.route-metric:                      10
"""

TESTCASE_ETHERNET_MOD_IPV4_INT_WITH_ROUTE_AND_METRIC_CLEAR = [
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "routes4": [],
        "state": "present",
        "_ansible_check_mode": False,
        "_ansible_diff": True,
    },
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "routes4_extended": [],
        "state": "present",
        "_ansible_check_mode": False,
        "_ansible_diff": True,
    },
]

TESTCASE_ETHERNET_MOD_IPV6_INT_WITH_ROUTE_AND_METRIC = [
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "routes6": ["fd2e:446f:d85d:5::/64 2001:beef:cafe:10::2"],
        "route_metric6": 10,
        "state": "present",
        "_ansible_check_mode": False,
    },
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "routes6_extended": [{"ip": "fd2e:446f:d85d:5::/64", "next_hop": "2001:beef:cafe:10::2"}],
        "route_metric6": 10,
        "state": "present",
        "_ansible_check_mode": False,
    },
]

TESTCASE_ETHERNET_MOD_IPV6_INT_WITH_ROUTE_AND_METRIC_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              ethernet_non_existant
connection.autoconnect:                 yes
ipv6.method:                            manual
ipv6.addresses:                         2001:beef:cafe:10::1/64
ipv6.routes:                            { ip = fd2e:446f:d85d:5::/64, nh = 2001:beef:cafe:10::2 }
ipv6.route-metric                       10
"""

TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_MULTIPLE_ROUTES = [
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "ifname": "ethernet_non_existant",
        "ip6": "2001:beef:cafe:10::1/64",
        "routes6": ["fd2e:446f:d85d:5::/64 2001:beef:cafe:10::2", "fd2e:8890:abcd:25::/64 2001:beef:cafe:10::5"],
        "method6": "manual",
        "state": "present",
        "_ansible_check_mode": False,
    },
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "ifname": "ethernet_non_existant",
        "ip6": "2001:beef:cafe:10::1/64",
        "routes6_extended": [
            {"ip": "fd2e:446f:d85d:5::/64", "next_hop": "2001:beef:cafe:10::2"},
            {"ip": "fd2e:8890:abcd:25::/64", "next_hop": "2001:beef:cafe:10::5"},
        ],
        "method6": "manual",
        "state": "present",
        "_ansible_check_mode": False,
    },
]

TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_MULTIPLE_ROUTES_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              ethernet_non_existant
connection.autoconnect:                 yes
ipv4.method:                            auto
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            manual
ipv6.addresses:                         2001:beef:cafe:10::1/64
ipv6.routes:                            { ip = fd2e:446f:d85d:5::/64, nh = 2001:beef:cafe:10::2 }; { ip = fd2e:8890:abcd:25::/64, nh = 2001:beef:cafe:10::5 }
ipv6.route-metric:                      -1
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
"""

TESTCASE_ETHERNET_ADD_SRIOV_VFS = [
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "ifname": "ethernet_non_existant",
        "sriov": {
            "total-vfs": 16,
            "vfs": "0 spoof-check=true vlans=100",
        },
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_ETHERNET_ADD_SRIOV_VFS_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              ethernet_non_existant
connection.autoconnect:                 yes
sriov.total-vfs:                        16
sriov.vfs:                              0 spoof-check=true vlans=100
"""

TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_ROUTE_AND_METRIC = [
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "ifname": "ethernet_non_existant",
        "method4": "disabled",
        "ip6": "2001:beef:cafe:10::1/64",
        "routes6": ["fd2e:446f:d85d:5::/64 2001:beef:cafe:10::2"],
        "route_metric6": 5,
        "method6": "manual",
        "state": "present",
        "_ansible_check_mode": False,
    },
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "ifname": "ethernet_non_existant",
        "method4": "disabled",
        "ip6": "2001:beef:cafe:10::1/64",
        "routes6_extended": [{"ip": "fd2e:446f:d85d:5::/64", "next_hop": "2001:beef:cafe:10::2"}],
        "route_metric6": 5,
        "method6": "manual",
        "state": "present",
        "_ansible_check_mode": False,
    },
]

TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_ROUTE_AND_METRIC_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              ethernet_non_existant
connection.autoconnect:                 yes
ipv4.method:                            auto
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            manual
ipv6.addresses:                         2001:beef:cafe:10::1/64
ipv6.routes:                            { ip = fd2e:446f:d85d:5::/64, nh = 2001:beef:cafe:10::2 }
ipv6.route-metric:                      5
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
"""

TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_MULTIPLE_ROUTES_AND_METRIC = [
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "ifname": "ethernet_non_existant",
        "method4": "disabled",
        "ip6": "2001:beef:cafe:10::1/64",
        "routes6": ["fd2e:446f:d85d:5::/64 2001:beef:cafe:10::2", "fd2e:8890:abcd:25::/64 2001:beef:cafe:10::5"],
        "route_metric6": 5,
        "method6": "manual",
        "state": "present",
        "_ansible_check_mode": False,
    },
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "ifname": "ethernet_non_existant",
        "method4": "disabled",
        "ip6": "2001:beef:cafe:10::1/64",
        "routes6_extended": [
            {"ip": "fd2e:446f:d85d:5::/64", "next_hop": "2001:beef:cafe:10::2"},
            {"ip": "fd2e:8890:abcd:25::/64", "next_hop": "2001:beef:cafe:10::5"},
        ],
        "route_metric6": 5,
        "method6": "manual",
        "state": "present",
        "_ansible_check_mode": False,
    },
]

TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_MULTIPLE_ROUTES_AND_METRIC_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              ethernet_non_existant
connection.autoconnect:                 yes
ipv4.method:                            auto
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            manual
ipv6.addresses:                         2001:beef:cafe:10::1/64
ipv6.routes:                            { ip = fd2e:446f:d85d:5::/64, nh = 2001:beef:cafe:10::2 }; { ip = fd2e:8890:abcd:25::/64, nh = 2001:beef:cafe:10::5 }
ipv6.route-metric:                      5
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
"""

TESTCASE_GENERIC_DNS4_SEARCH = [
    {
        "type": "generic",
        "conn_name": "non_existent_nw_device",
        "ifname": "generic_non_existant",
        "ip4": "10.10.10.10/24",
        "gw4": "10.10.10.1",
        "state": "present",
        "dns4_search": "search.redhat.com",
        "dns6_search": "search6.redhat.com",
        "_ansible_check_mode": False,
    }
]

TESTCASE_GENERIC_DNS4_SEARCH_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              generic_non_existant
connection.autoconnect:                 yes
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/24
ipv4.gateway:                           10.10.10.1
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.dns-search:                        search.redhat.com
ipv4.may-fail:                          yes
ipv6.dns-search:                        search6.redhat.com
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
"""

TESTCASE_GENERIC_DNS4_OPTIONS = [
    {
        "type": "generic",
        "conn_name": "non_existent_nw_device",
        "ifname": "generic_non_existant",
        "ip4": "10.10.10.10/24",
        "gw4": "10.10.10.1",
        "state": "present",
        "dns4_options": [],
        "dns6_options": [],
        "_ansible_check_mode": False,
    }
]

TESTCASE_GENERIC_DNS4_OPTIONS_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              generic_non_existant
connection.autoconnect:                 yes
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/24
ipv4.gateway:                           10.10.10.1
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.dns-options:                       --
ipv4.may-fail:                          yes
ipv6.dns-options:                       --
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
"""

TESTCASE_GENERIC_ZONE = [
    {
        "type": "generic",
        "conn_name": "non_existent_nw_device",
        "ifname": "generic_non_existant",
        "ip4": "10.10.10.10/24",
        "gw4": "10.10.10.1",
        "state": "present",
        "zone": "external",
        "_ansible_check_mode": False,
    }
]

TESTCASE_GENERIC_ZONE_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              generic_non_existant
connection.autoconnect:                 yes
connection.zone:                        external
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/24
ipv4.gateway:                           10.10.10.1
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
"""

TESTCASE_GENERIC_ZONE_ONLY = [
    {
        "type": "generic",
        "conn_name": "non_existent_nw_device",
        "ifname": "generic_non_existant",
        "state": "present",
        "zone": "public",
        "_ansible_check_mode": False,
    }
]

TESTCASE_BOND = [
    {
        "type": "bond",
        "conn_name": "non_existent_nw_device",
        "ifname": "bond_non_existant",
        "mode": "active-backup",
        "xmit_hash_policy": "layer3+4",
        "ip4": "10.10.10.10/24",
        "gw4": "10.10.10.1",
        "state": "present",
        "primary": "non_existent_primary",
        "_ansible_check_mode": False,
    }
]

TESTCASE_BOND_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              bond_non_existant
connection.autoconnect:                 yes
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/24
ipv4.gateway:                           10.10.10.1
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
bond.options:                           mode=active-backup,primary=non_existent_primary,xmit_hash_policy=layer3+4
"""

TESTCASE_BRIDGE = [
    {
        "type": "bridge",
        "conn_name": "non_existent_nw_device",
        "ifname": "br0_non_existant",
        "ip4": "10.10.10.10/24",
        "gw4": "10.10.10.1",
        "mac": "52:54:00:ab:cd:ef",
        "maxage": 100,
        "stp": True,
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_BRIDGE_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              br0_non_existant
connection.autoconnect:                 yes
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/24
ipv4.gateway:                           10.10.10.1
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
bridge.mac-address:                     52:54:00:AB:CD:EF
bridge.stp:                             yes
bridge.max-age:                         100
bridge.ageing-time:                     300
bridge.hello-time:                      2
bridge.priority:                        128
bridge.forward-delay:                   15
"""

TESTCASE_BRIDGE_SLAVE = [
    {
        "type": "bridge-slave",
        "conn_name": "non_existent_nw_device",
        "ifname": "br0_non_existant",
        "hairpin": True,
        "path_cost": 100,
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_BRIDGE_SLAVE_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              br0_non_existant
connection.autoconnect:                 yes
connection.slave-type:                  bridge
ipv4.never-default:                     no
bridge-port.path-cost:                  100
bridge-port.hairpin-mode:               yes
bridge-port.priority:                   32
"""

TESTCASE_TEAM = [
    {
        "type": "team",
        "conn_name": "non_existent_nw_device",
        "ifname": "team0_non_existant",
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_TEAM_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              team0_non_existant
connection.autoconnect:                 yes
connection.type:                        team
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
team.runner:                            roundrobin
team.runner-fast-rate:                  no
"""

TESTCASE_TEAM_HWADDR_POLICY_FAILS = [
    {
        "type": "team",
        "conn_name": "non_existent_nw_device",
        "ifname": "team0_non_existant",
        "runner_hwaddr_policy": "by_active",
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_TEAM_RUNNER_FAST_RATE = [
    {
        "type": "team",
        "conn_name": "non_existent_nw_device",
        "ifname": "team0_non_existant",
        "runner": "lacp",
        "runner_fast_rate": True,
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_TEAM_RUNNER_FAST_RATE_FAILS = [
    {
        "type": "team",
        "conn_name": "non_existent_nw_device",
        "ifname": "team0_non_existant",
        "runner_fast_rate": True,
        "state": "present",
        "_ansible_check_mode": False,
    },
    {
        "type": "team",
        "conn_name": "non_existent_nw_device",
        "ifname": "team0_non_existant",
        "state": "present",
        "runner_fast_rate": False,
        "_ansible_check_mode": False,
    },
    {
        "type": "team",
        "conn_name": "non_existent_nw_device",
        "ifname": "team0_non_existant",
        "state": "present",
        "runner": "activebackup",
        "runner_fast_rate": False,
        "_ansible_check_mode": False,
    },
    {
        "type": "team",
        "conn_name": "non_existent_nw_device",
        "ifname": "team0_non_existant",
        "state": "present",
        "runner": "activebackup",
        "runner_fast_rate": True,
        "_ansible_check_mode": False,
    },
]

TESTCASE_TEAM_RUNNER_FAST_RATE_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              team0_non_existant
connection.autoconnect:                 yes
connection.type:                        team
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
team.runner:                            lacp
team.runner-fast-rate:                  yes
"""

TESTCASE_TEAM_SLAVE = [
    {
        "type": "team-slave",
        "conn_name": "non_existent_nw_slaved_device",
        "ifname": "generic_slaved_non_existant",
        "master": "team0_non_existant",
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_TEAM_SLAVE_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_slaved_device
connection.interface-name:              generic_slaved_non_existant
connection.autoconnect:                 yes
connection.master:                      team0_non_existant
connection.slave-type:                  team
802-3-ethernet.mtu:                     auto
"""

TESTCASE_VLAN = [
    {
        "type": "vlan",
        "conn_name": "non_existent_nw_device",
        "ifname": "vlan_not_exists",
        "ip4": "10.10.10.10/24",
        "gw4": "10.10.10.1",
        "vlanid": 10,
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_VLAN_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              vlan_not_exists
connection.autoconnect:                 yes
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/24
ipv4.gateway:                           10.10.10.1
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
vlan.id:                                10
802-3-ethernet.mtu:                     auto
"""

TESTCASE_VXLAN = [
    {
        "type": "vxlan",
        "conn_name": "non_existent_nw_device",
        "ifname": "vxlan-existent_nw_device",
        "vxlan_id": 11,
        "vxlan_local": "192.168.225.5",
        "vxlan_remote": "192.168.225.6",
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_VXLAN_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              vxlan-existent_nw_device
connection.autoconnect:                 yes
vxlan.id:                               11
vxlan.local:                            192.168.225.5
vxlan.remote:                           192.168.225.6
"""

TESTCASE_VXLAN_MULTICAST = [
    {
        "type": "vxlan",
        "conn_name": "vxlan_multicast_test",
        "ifname": "vxlan-device",
        "vxlan_id": 17,
        "vxlan_parent": "eth1",
        "vxlan_local": "192.168.1.2",
        "vxlan_remote": "239.192.0.17",
        "slave_type": "bridge",
        "master": "br0",
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_VXLAN_MULTICAST_SHOW_OUTPUT = """\
connection.id:                          vxlan_multicast_test
connection.interface-name:              vxlan-device
connection.autoconnect:                 yes
connection.slave-type:                  bridge
connection.master:                      br0
vxlan.id:                               17
vxlan.parent:                           eth1
vxlan.local:                            192.168.1.2
vxlan.remote:                           239.192.0.17
"""

TESTCASE_GRE = [
    {
        "type": "gre",
        "conn_name": "non_existent_nw_device",
        "ifname": "gre-existent_nw_device",
        "ip_tunnel_dev": "non_existent_gre_device",
        "ip_tunnel_local": "192.168.225.5",
        "ip_tunnel_remote": "192.168.225.6",
        "ip_tunnel_input_key": "1",
        "ip_tunnel_output_key": "2",
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_GRE_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              gre-existent_nw_device
connection.autoconnect:                 yes
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
ip-tunnel.mode:                         gre
ip-tunnel.parent:                       non_existent_gre_device
ip-tunnel.local:                        192.168.225.5
ip-tunnel.remote:                       192.168.225.6
ip-tunnel.input-key:                    1
ip-tunnel.output-key:                   2
"""

TESTCASE_IPIP = [
    {
        "type": "ipip",
        "conn_name": "non_existent_nw_device",
        "ifname": "ipip-existent_nw_device",
        "ip_tunnel_dev": "non_existent_ipip_device",
        "ip_tunnel_local": "192.168.225.5",
        "ip_tunnel_remote": "192.168.225.6",
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_IPIP_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              ipip-existent_nw_device
connection.autoconnect:                 yes
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
ip-tunnel.mode:                         ipip
ip-tunnel.parent:                       non_existent_ipip_device
ip-tunnel.local:                        192.168.225.5
ip-tunnel.remote:                       192.168.225.6
"""

TESTCASE_SIT = [
    {
        "type": "sit",
        "conn_name": "non_existent_nw_device",
        "ifname": "sit-existent_nw_device",
        "ip_tunnel_dev": "non_existent_sit_device",
        "ip_tunnel_local": "192.168.225.5",
        "ip_tunnel_remote": "192.168.225.6",
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_SIT_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              sit-existent_nw_device
connection.autoconnect:                 yes
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
ip-tunnel.mode:                         sit
ip-tunnel.parent:                       non_existent_sit_device
ip-tunnel.local:                        192.168.225.5
ip-tunnel.remote:                       192.168.225.6
"""

TESTCASE_ETHERNET_DHCP = [
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "ifname": "ethernet_non_existant",
        "dhcp_client_id": "00:11:22:AA:BB:CC:DD",
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_ETHERNET_DHCP_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              ethernet_non_existant
connection.autoconnect:                 yes
802-3-ethernet.mtu:                     auto
ipv4.method:                            auto
ipv4.dhcp-client-id:                    00:11:22:AA:BB:CC:DD
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
"""

TESTCASE_ETHERNET_STATIC = [
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "ifname": "ethernet_non_existant",
        "ip4": "10.10.10.10/24",
        "gw4": "10.10.10.1",
        "dns4": ["1.1.1.1", "8.8.8.8"],
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_LOOPBACK = [
    {
        "type": "loopback",
        "conn_name": "lo",
        "ifname": "lo",
        "ip4": "127.0.0.1/8",
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_LOOPBACK_MODIFY = [
    {
        "type": "loopback",
        "conn_name": "lo",
        "ifname": "lo",
        "ip4": ["127.0.0.1/8", "127.0.0.2/8"],
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_ETHERNET_STATIC_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              ethernet_non_existant
connection.autoconnect:                 yes
802-3-ethernet.mtu:                     auto
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/24
ipv4.gateway:                           10.10.10.1
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv4.dns:                               1.1.1.1,8.8.8.8
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
"""

TESTCASE_LOOPBACK_SHOW_OUTPUT = """\
connection.id:                          lo
connection.interface-name:              lo
connection.autoconnect:                 yes
ipv4.method:                            manual
ipv4.addresses:                         127.0.0.1/8
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            manual
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
"""

TESTCASE_ETHERNET_STATIC_MULTIPLE_IP4_ADDRESSES = [
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "ifname": "ethernet_non_existant",
        "ip4": ["10.10.10.10/32", "10.10.20.10/32"],
        "gw4": "10.10.10.1",
        "dns4": ["1.1.1.1", "8.8.8.8"],
        "state": "present",
        "_ansible_check_mode": False,
    },
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "ifname": "ethernet_non_existant",
        "ip4": ["10.10.10.10", "10.10.20.10"],
        "gw4": "10.10.10.1",
        "dns4": ["1.1.1.1", "8.8.8.8"],
        "state": "present",
        "_ansible_check_mode": False,
    },
]

TESTCASE_ETHERNET_STATIC_IP6_PRIVACY_AND_ADDR_GEN_MODE = [
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "ifname": "ethernet_non_existant",
        "ip6": "2001:db8::cafe/128",
        "gw6": "2001:db8::cafa",
        "dns6": ["2001:4860:4860::8888"],
        "state": "present",
        "ip_privacy6": "prefer-public-addr",
        "addr_gen_mode6": "eui64",
        "_ansible_check_mode": False,
    }
]

TESTCASE_ETHERNET_STATIC_MULTIPLE_IP6_ADDRESSES = [
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "ifname": "ethernet_non_existant",
        "ip6": ["2001:db8::cafe/128", "2002:db8::cafe/128"],
        "gw6": "2001:db8::cafa",
        "dns6": ["2001:4860:4860::8888", "2001:4860:4860::8844"],
        "state": "present",
        "_ansible_check_mode": False,
    },
    {
        "type": "ethernet",
        "conn_name": "non_existent_nw_device",
        "ifname": "ethernet_non_existant",
        "ip6": ["2001:db8::cafe", "2002:db8::cafe"],
        "gw6": "2001:db8::cafa",
        "dns6": ["2001:4860:4860::8888", "2001:4860:4860::8844"],
        "state": "present",
        "_ansible_check_mode": False,
    },
]

TESTCASE_ETHERNET_STATIC_MULTIPLE_IP4_ADDRESSES_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              ethernet_non_existant
connection.autoconnect:                 yes
802-3-ethernet.mtu:                     auto
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/32, 10.10.20.10/32
ipv4.gateway:                           10.10.10.1
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv4.dns:                               1.1.1.1,8.8.8.8
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
"""

TESTCASE_ETHERNET_STATIC_IP6_ADDRESS_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              ethernet_non_existant
connection.autoconnect:                 yes
802-3-ethernet.mtu:                     auto
ipv6.method:                            manual
ipv6.addresses:                         2001:db8::cafe/128
ipv6.gateway:                           2001:db8::cafa
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
ipv6.never-default:                     no
ipv6.may-fail:                          yes
ipv6.dns:                               2001:4860:4860::8888,2001:4860:4860::8844
ipv4.method:                            disabled
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
"""


TESTCASE_ETHERNET_STATIC_MULTIPLE_IP6_ADDRESSES_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              ethernet_non_existant
connection.autoconnect:                 yes
802-3-ethernet.mtu:                     auto
ipv6.method:                            manual
ipv6.addresses:                         2001:db8::cafe/128, 2002:db8::cafe/128
ipv6.gateway:                           2001:db8::cafa
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
ipv6.never-default:                     no
ipv6.may-fail:                          yes
ipv6.dns:                               2001:4860:4860::8888,2001:4860:4860::8844
ipv4.method:                            disabled
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
"""

TESTCASE_WIRELESS = [
    {
        "type": "wifi",
        "conn_name": "non_existent_nw_device",
        "ifname": "wireless_non_existant",
        "ip4": "10.10.10.10/24",
        "ssid": "Brittany",
        "wifi": {
            "hidden": True,
            "mode": "ap",
        },
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_SECURE_WIRELESS = [
    {
        "type": "wifi",
        "conn_name": "non_existent_nw_device",
        "ifname": "wireless_non_existant",
        "ip4": "10.10.10.10/24",
        "ssid": "Brittany",
        "wifi_sec": {
            "key-mgmt": "wpa-psk",
            "psk": "VERY_SECURE_PASSWORD",
        },
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_DEFAULT_WIRELESS_SHOW_OUTPUT = """\
802-11-wireless.ssid:                   --
802-11-wireless.mode:                   infrastructure
802-11-wireless.band:                   --
802-11-wireless.channel:                0
802-11-wireless.bssid:                  --
802-11-wireless.rate:                   0
802-11-wireless.tx-power:               0
802-11-wireless.mac-address:            --
802-11-wireless.cloned-mac-address:     --
802-11-wireless.generate-mac-address-mask:--
802-11-wireless.mac-address-blacklist:  --
802-11-wireless.mac-address-randomization:default
802-11-wireless.mtu:                    auto
802-11-wireless.seen-bssids:            --
802-11-wireless.hidden:                 no
802-11-wireless.powersave:              0 (default)
802-11-wireless.wake-on-wlan:           0x1 (default)
802-11-wireless.ap-isolation:           -1 (default)
"""

TESTCASE_DEFAULT_SECURE_WIRELESS_SHOW_OUTPUT = (
    TESTCASE_DEFAULT_WIRELESS_SHOW_OUTPUT
    + """\
802-11-wireless-security.key-mgmt:      --
802-11-wireless-security.wep-tx-keyidx: 0
802-11-wireless-security.auth-alg:      --
802-11-wireless-security.proto:         --
802-11-wireless-security.pairwise:      --
802-11-wireless-security.group:         --
802-11-wireless-security.pmf:           0 (default)
802-11-wireless-security.leap-username: --
802-11-wireless-security.wep-key0:      --
802-11-wireless-security.wep-key1:      --
802-11-wireless-security.wep-key2:      --
802-11-wireless-security.wep-key3:      --
802-11-wireless-security.wep-key-flags: 0 (none)
802-11-wireless-security.wep-key-type:  unknown
802-11-wireless-security.psk:           testingtestingtesting
802-11-wireless-security.psk-flags:     0 (none)
802-11-wireless-security.leap-password: --
802-11-wireless-security.leap-password-flags:0 (none)
802-11-wireless-security.wps-method:    0x0 (default)
802-11-wireless-security.fils:          0 (default)
"""
)


TESTCASE_DUMMY_STATIC = [
    {
        "type": "dummy",
        "conn_name": "non_existent_nw_device",
        "ifname": "dummy_non_existant",
        "ip4": "10.10.10.10/24",
        "gw4": "10.10.10.1",
        "dns4": ["1.1.1.1", "8.8.8.8"],
        "ip6": "2001:db8::1/128",
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_DUMMY_STATIC_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              dummy_non_existant
connection.autoconnect:                 yes
802-3-ethernet.mtu:                     auto
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/24
ipv4.gateway:                           10.10.10.1
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv4.dns:                               1.1.1.1,8.8.8.8
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
ipv6.method:                            manual
ipv6.addresses:                         2001:db8::1/128
"""

TESTCASE_DUMMY_STATIC_WITHOUT_MTU_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              dummy_non_existant
connection.autoconnect:                 yes
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/24
ipv4.gateway:                           10.10.10.1
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv4.dns:                               1.1.1.1,8.8.8.8
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
ipv6.method:                            manual
ipv6.addresses:                         2001:db8::1/128
"""

TESTCASE_DUMMY_STATIC_WITH_CUSTOM_MTU_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              dummy_non_existant
connection.autoconnect:                 yes
802-3-ethernet.mtu:                     1500
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/24
ipv4.gateway:                           10.10.10.1
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv4.dns:                               1.1.1.1,8.8.8.8
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
ipv6.method:                            manual
ipv6.addresses:                         2001:db8::1/128
"""

TESTCASE_ETHERNET_STATIC_IP6_PRIVACY_AND_ADDR_GEN_MODE_UNCHANGED_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              ethernet_non_existant
connection.autoconnect:                 yes
802-3-ethernet.mtu:                     auto
ipv6.method:                            manual
ipv6.addresses:                         2001:db8::cafe/128
ipv6.gateway:                           2001:db8::cafa
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
ipv6.never-default:                     no
ipv6.may-fail:                          yes
ipv6.ip6-privacy:                       1 (enabled, prefer public IP)
ipv6.addr-gen-mode:                     eui64
ipv6.dns:                               2001:4860:4860::8888
ipv4.method:                            disabled
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
"""

TESTCASE_GSM = [
    {
        "type": "gsm",
        "conn_name": "non_existent_nw_device",
        "ifname": "gsm_non_existant",
        "gsm": {
            "apn": "internet.telekom",
            "username": "t-mobile",
            "password": "tm",
            "pin": "1234",
        },
        "method4": "auto",
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_GSM_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.type:                        gsm
connection.interface-name:              gsm_non_existant
connection.autoconnect:                 yes
ipv4.method:                            auto
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
gsm.auto-config:                        no
gsm.number:                             --
gsm.username:                           t-mobile
gsm.password:                           tm
gsm.password-flags:                     0 (none)
gsm.apn:                                "internet.telekom"
gsm.network-id:                         --
gsm.pin:                                1234
gsm.pin-flags:                          0 (none)
gsm.home-only:                          no
gsm.device-id:                          --
gsm.sim-id:                             --
gsm.sim-operator-id:                    --
gsm.mtu:                                auto
"""

TESTCASE_WIREGUARD = [
    {
        "type": "wireguard",
        "conn_name": "non_existent_nw_device",
        "ifname": "wg_non_existant",
        "wireguard": {
            "listen-port": "51820",
            "private-key": "<hidden>",
        },
        "method4": "manual",
        "ip4": "10.10.10.10/24",
        "method6": "manual",
        "ip6": "2001:db8::1/128",
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_WIREGUARD_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.type:                        wireguard
connection.interface-name:              wg_non_existant
connection.autoconnect:                 yes
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/24
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv6.method:                            manual
ipv6.addresses:                         2001:db8::1/128
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
wireguard.private-key:                  <hidden>
wireguard.private-key-flags:            0 (none)
wireguard.listen-port:                  51820
wireguard.fwmark:                       0x0
wireguard.peer-routes:                  yes
wireguard.mtu:                          0
wireguard.ip4-auto-default-route:       -1 (default)
wireguard.ip6-auto-default-route:       -1 (default)
"""

TESTCASE_VPN_L2TP = [
    {
        "type": "vpn",
        "conn_name": "vpn_l2tp",
        "vpn": {
            "permissions": "brittany",
            "service-type": "org.freedesktop.NetworkManager.l2tp",
            "gateway": "vpn.example.com",
            "password-flags": "2",
            "user": "brittany",
            "ipsec-enabled": "true",
            "ipsec-psk": "QnJpdHRhbnkxMjM=",
        },
        "gw4_ignore_auto": True,
        "routes4": ["192.168.200.0/24"],
        "autoconnect": "false",
        "state": "present",
        "_ansible_check_mode": False,
    },
]

TESTCASE_VPN_L2TP_SHOW_OUTPUT = """\
connection.id:                          vpn_l2tp
connection.type:                        vpn
connection.autoconnect:                 no
connection.permissions:                 brittany
ipv4.method:                            auto
ipv4.routes:                            { ip = 192.168.200.0/24 }
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                yes
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
vpn.service-type:                       org.freedesktop.NetworkManager.l2tp
vpn.data:                               gateway = vpn.example.com, ipsec-enabled = true, ipsec-psk = QnJpdHRhbnkxMjM=, password-flags = 2, user = brittany
vpn.secrets:                            ipsec-psk = QnJpdHRhbnkxMjM=
vpn.persistent:                         no
vpn.timeout:                            0
"""

TESTCASE_VPN_PPTP = [
    {
        "type": "vpn",
        "conn_name": "vpn_pptp",
        "vpn": {
            "permissions": "brittany",
            "service-type": "org.freedesktop.NetworkManager.pptp",
            "gateway": "vpn.example.com",
            "password-flags": "2",
            "user": "brittany",
        },
        "autoconnect": "false",
        "state": "present",
        "_ansible_check_mode": False,
    },
]

TESTCASE_VPN_PPTP_SHOW_OUTPUT = """\
connection.id:                          vpn_pptp
connection.type:                        vpn
connection.autoconnect:                 no
connection.permissions:                 brittany
ipv4.method:                            auto
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
vpn.service-type:                       org.freedesktop.NetworkManager.pptp
vpn.data:                               gateway=vpn.example.com, password-flags=2, user=brittany
"""

TESTCASE_INFINIBAND_STATIC = [
    {
        "type": "infiniband",
        "conn_name": "non_existent_nw_device",
        "ifname": "infiniband_non_existant",
        "ip4": "10.10.10.10/24",
        "gw4": "10.10.10.1",
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_INFINIBAND_STATIC_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.type:                        infiniband
connection.interface-name:              infiniband_non_existant
connection.autoconnect:                 yes
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/24
ipv4.gateway:                           10.10.10.1
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
infiniband.mtu:                         auto
infiniband.transport-mode:              datagram
"""

TESTCASE_INFINIBAND_STATIC_MODIFY_TRANSPORT_MODE = [
    {
        "type": "infiniband",
        "conn_name": "non_existent_nw_device",
        "transport_mode": "connected",
        "state": "present",
        "_ansible_check_mode": False,
    },
]

TESTCASE_INFINIBAND_STATIC_MODIFY_TRANSPORT_MODE_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              infiniband_non_existant
infiniband.transport_mode:              connected
"""

TESTCASE_MACVLAN = [
    {
        "type": "macvlan",
        "conn_name": "non_existent_nw_device",
        "ifname": "macvlan_non_existant",
        "macvlan": {
            "mode": "2",
            "parent": "non_existent_parent",
        },
        "method4": "manual",
        "ip4": "10.10.10.10/24",
        "method6": "manual",
        "ip6": "2001:db8::1/128",
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_MACVLAN_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.type:                        macvlan
connection.interface-name:              macvlan_non_existant
connection.autoconnect:                 yes
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/24
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv6.method:                            manual
ipv6.addresses:                         2001:db8::1/128
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
macvlan.parent:                         non_existent_parent
macvlan.mode:                           2 (bridge)
macvlan.promiscuous:                    yes
macvlan.tap:                            no
"""

TESTCASE_VRF = [
    {
        "type": "vrf",
        "conn_name": "non_existent_nw_device",
        "ifname": "vrf_not_exists",
        "ip4": "10.10.10.10/24",
        "gw4": "10.10.10.1",
        "table": 10,
        "state": "present",
        "_ansible_check_mode": False,
    }
]

TESTCASE_VRF_SHOW_OUTPUT = """\
connection.id:                          non_existent_nw_device
connection.interface-name:              vrf_not_exists
connection.autoconnect:                 yes
ipv4.method:                            manual
ipv4.addresses:                         10.10.10.10/24
ipv4.gateway:                           10.10.10.1
ipv4.ignore-auto-dns:                   no
ipv4.ignore-auto-routes:                no
ipv4.never-default:                     no
ipv4.may-fail:                          yes
ipv6.method:                            auto
ipv6.ignore-auto-dns:                   no
ipv6.ignore-auto-routes:                no
table:                                  10
802-3-ethernet.mtu:                     auto
"""


def mocker_set(
    mocker, connection_exists=False, execute_return=(0, "", ""), execute_side_effect=None, changed_return=None
):
    """
    Common mocker object
    """
    get_bin_path = mocker.patch("ansible.module_utils.basic.AnsibleModule.get_bin_path")
    get_bin_path.return_value = "/usr/bin/nmcli"
    connection = mocker.patch.object(nmcli.Nmcli, "connection_exists")
    connection.return_value = connection_exists
    execute_command = mocker.patch.object(nmcli.Nmcli, "execute_command")
    if execute_return:
        execute_command.return_value = execute_return
    if execute_side_effect:
        execute_command.side_effect = execute_side_effect
    if changed_return:
        is_connection_changed = mocker.patch.object(nmcli.Nmcli, "is_connection_changed")
        is_connection_changed.return_value = changed_return


@pytest.fixture
def mocked_generic_connection_create(mocker):
    mocker_set(mocker)


@pytest.fixture
def mocked_connection_exists(mocker):
    mocker_set(mocker, connection_exists=True)


@pytest.fixture
def mocked_generic_connection_modify(mocker):
    mocker_set(mocker, connection_exists=True, changed_return=(True, dict()))


# TODO: overridden below!
# @pytest.fixture
# def mocked_generic_connection_unchanged(mocker):
#     mocker_set(mocker,
#                connection_exists=True,
#                execute_return=(0, TESTCASE_GENERIC_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_generic_connection_unchanged(mocker):
    mocker_set(
        mocker, connection_exists=True, execute_return=(0, TESTCASE_GENERIC_MODIFY_ROUTING_RULES_SHOW_OUTPUT, "")
    )


@pytest.fixture
def mocked_generic_connection_dns_search_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_GENERIC_DNS4_SEARCH_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_generic_connection_dns_options_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_GENERIC_DNS4_OPTIONS_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_generic_connection_zone_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_GENERIC_ZONE_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_bond_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_BOND_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_bridge_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_BRIDGE_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_bridge_slave_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_BRIDGE_SLAVE_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_team_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_TEAM_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_team_runner_fast_rate_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_TEAM_RUNNER_FAST_RATE_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_team_slave_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_TEAM_SLAVE_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_vlan_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_VLAN_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_vxlan_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_VXLAN_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_gre_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_GRE_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_ipip_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_IPIP_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_sit_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_SIT_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_ethernet_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_ETHERNET_DHCP, ""))


@pytest.fixture
def mocked_ethernet_connection_dhcp_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_ETHERNET_DHCP_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_ethernet_connection_static_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_ETHERNET_STATIC_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_ethernet_connection_static_multiple_ip4_addresses_unchanged(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=(0, TESTCASE_ETHERNET_STATIC_MULTIPLE_IP4_ADDRESSES_SHOW_OUTPUT, ""),
    )


@pytest.fixture
def mocked_ethernet_connection_static_ip6_privacy_and_addr_gen_mode_unchange(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=(0, TESTCASE_ETHERNET_STATIC_IP6_PRIVACY_AND_ADDR_GEN_MODE_UNCHANGED_OUTPUT, ""),
    )


@pytest.fixture
def mocked_ethernet_connection_static_multiple_ip6_addresses_unchanged(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=(0, TESTCASE_ETHERNET_STATIC_MULTIPLE_IP6_ADDRESSES_SHOW_OUTPUT, ""),
    )


@pytest.fixture
def mocked_ethernet_connection_static_modify(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_ETHERNET_STATIC_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.fixture
def mocked_ethernet_connection_with_ipv6_static_address_static_route_create(mocker):
    mocker_set(
        mocker,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_ROUTE_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.fixture
def mocked_ethernet_connection_with_ipv4_static_address_static_route_metric_modify(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_ETHERNET_MOD_IPV4_INT_WITH_ROUTE_AND_METRIC_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.fixture
def mocked_ethernet_connection_with_ipv4_static_address_static_route_metric_clear(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_ETHERNET_MOD_IPV4_INT_WITH_ROUTE_AND_METRIC_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.fixture
def mocked_ethernet_connection_with_ipv6_static_address_static_route_metric_modify(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_ETHERNET_MOD_IPV6_INT_WITH_ROUTE_AND_METRIC_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.fixture
def mocked_ethernet_connection_with_ipv6_static_address_multiple_static_routes_create(mocker):
    mocker_set(
        mocker,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_MULTIPLE_ROUTES_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.fixture
def mocked_ethernet_connection_with_sriov_vfs_create(mocker):
    mocker_set(mocker, execute_return=(0, TESTCASE_ETHERNET_ADD_SRIOV_VFS_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_ethernet_connection_with_ipv6_static_address_static_route_with_metric_create(mocker):
    mocker_set(
        mocker,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_ROUTE_AND_METRIC_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.fixture
def mocked_ethernet_connection_with_ipv6_static_address_multiple_static_routes_with_metric_create(mocker):
    mocker_set(
        mocker,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_MULTIPLE_ROUTES_AND_METRIC_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.fixture
def mocked_ethernet_connection_with_ipv6_address_static_modify(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_ETHERNET_STATIC_IP6_ADDRESS_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.fixture
def mocked_ethernet_connection_dhcp_to_static(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_ETHERNET_DHCP_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.fixture
def mocked_wireless_create(mocker):
    mocker_set(
        mocker,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_DEFAULT_WIRELESS_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.fixture
def mocked_secure_wireless_create(mocker):
    mocker_set(
        mocker,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_DEFAULT_SECURE_WIRELESS_SHOW_OUTPUT, ""),
            (0, "", ""),
            (0, "", ""),
        ),
    )


@pytest.fixture
def mocked_secure_wireless_create_failure(mocker):
    mocker_set(
        mocker,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_DEFAULT_SECURE_WIRELESS_SHOW_OUTPUT, ""),
            (1, "", ""),
        ),
    )


@pytest.fixture
def mocked_secure_wireless_modify(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_DEFAULT_SECURE_WIRELESS_SHOW_OUTPUT, ""),
            (0, "", ""),
            (0, "", ""),
            (0, "", ""),
        ),
    )


@pytest.fixture
def mocked_secure_wireless_modify_failure(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_DEFAULT_SECURE_WIRELESS_SHOW_OUTPUT, ""),
            (0, "", ""),
            (1, "", ""),
        ),
    )


@pytest.fixture
def mocked_dummy_connection_static_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_DUMMY_STATIC_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_dummy_connection_static_without_mtu_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_DUMMY_STATIC_WITHOUT_MTU_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_dummy_connection_static_with_custom_mtu_modify(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_DUMMY_STATIC_WITH_CUSTOM_MTU_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.fixture
def mocked_gsm_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_GSM_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_wireguard_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_WIREGUARD_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_vpn_l2tp_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_VPN_L2TP_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_vpn_pptp_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_VPN_PPTP_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_infiniband_connection_static_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_INFINIBAND_STATIC_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_infiniband_connection_static_transport_mode_connected_modify(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_INFINIBAND_STATIC_MODIFY_TRANSPORT_MODE_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.fixture
def mocked_macvlan_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_MACVLAN_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_generic_connection_diff_check(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_GENERIC_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_loopback_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_LOOPBACK_SHOW_OUTPUT, ""))


@pytest.fixture
def mocked_loopback_connection_modify(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_LOOPBACK_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.fixture
def mocked_vrf_connection_unchanged(mocker):
    mocker_set(mocker, connection_exists=True, execute_return=(0, TESTCASE_VRF_SHOW_OUTPUT, ""))


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_BOND, indirect=["patch_ansible_module"])
def test_bond_connection_create(mocked_generic_connection_create, capfd):
    """
    Test : Bond connection created
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "bond"
    assert args[0][5] == "con-name"
    assert args[0][6] == "non_existent_nw_device"

    for param in [
        "ipv4.gateway",
        "primary",
        "connection.autoconnect",
        "connection.interface-name",
        "bond_non_existant",
        "mode",
        "active-backup",
        "ipv4.addresses",
        "+bond.options",
        "xmit_hash_policy=layer3+4",
    ]:
        assert param in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.skip(reason="Currently broken")  # TODO: fix me!
@pytest.mark.parametrize("patch_ansible_module", TESTCASE_BOND, indirect=["patch_ansible_module"])
def test_bond_connection_unchanged(mocked_bond_connection_unchanged, capfd):
    """
    Test : Bond connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GENERIC, indirect=["patch_ansible_module"])
def test_generic_connection_create(mocked_generic_connection_create, capfd):
    """
    Test : Generic connection created
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "generic"
    assert args[0][5] == "con-name"
    assert args[0][6] == "non_existent_nw_device"

    for param in ["connection.autoconnect", "ipv4.gateway", "ipv4.addresses"]:
        assert param in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GENERIC, indirect=["patch_ansible_module"])
def test_generic_connection_modify(mocked_generic_connection_modify, capfd):
    """
    Test : Generic connection modify
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "modify"
    assert args[0][3] == "non_existent_nw_device"

    for param in ["ipv4.gateway", "ipv4.addresses"]:
        assert param in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GENERIC, indirect=["patch_ansible_module"])
def test_generic_connection_unchanged(mocked_generic_connection_unchanged, capfd):
    """
    Test : Generic connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_GENERIC_MODIFY_ROUTING_RULES, indirect=["patch_ansible_module"]
)
def test_generic_connection_modify_routing_rules4(mocked_generic_connection_create, capfd):
    """
    Test : Generic connection modified with routing-rules4
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert "ipv4.routing-rules" in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GENERIC_DNS4_SEARCH, indirect=["patch_ansible_module"])
def test_generic_connection_create_dns_search(mocked_generic_connection_create, capfd):
    """
    Test : Generic connection created with dns search
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert "ipv4.dns-search" in args[0]
    assert "ipv6.dns-search" in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GENERIC_DNS4_SEARCH, indirect=["patch_ansible_module"])
def test_generic_connection_modify_dns_search(mocked_generic_connection_create, capfd):
    """
    Test : Generic connection modified with dns search
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert "ipv4.dns-search" in args[0]
    assert "ipv6.dns-search" in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GENERIC_DNS4_SEARCH, indirect=["patch_ansible_module"])
def test_generic_connection_dns_search_unchanged(mocked_generic_connection_dns_search_unchanged, capfd):
    """
    Test : Generic connection with dns search unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GENERIC_DNS4_OPTIONS, indirect=["patch_ansible_module"])
def test_generic_connection_create_dns_options(mocked_generic_connection_create, capfd):
    """
    Test : Generic connection created with dns options
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert "ipv4.dns-options" in args[0]
    assert "ipv6.dns-options" in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GENERIC_DNS4_OPTIONS, indirect=["patch_ansible_module"])
def test_generic_connection_modify_dns_options(mocked_generic_connection_create, capfd):
    """
    Test : Generic connection modified with dns options
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert "ipv4.dns-options" in args[0]
    assert "ipv6.dns-options" in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GENERIC_DNS4_OPTIONS, indirect=["patch_ansible_module"])
def test_generic_connection_dns_options_unchanged(mocked_generic_connection_dns_options_unchanged, capfd):
    """
    Test : Generic connection with dns options unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_CONNECTION, indirect=["patch_ansible_module"])
def test_dns4_none(mocked_connection_exists, capfd):
    """
    Test if DNS4 param is None
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GENERIC_ZONE, indirect=["patch_ansible_module"])
def test_generic_connection_create_zone(mocked_generic_connection_create, capfd):
    """
    Test : Generic connection created with zone
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert "connection.zone" in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GENERIC_ZONE, indirect=["patch_ansible_module"])
def test_generic_connection_modify_zone(mocked_generic_connection_create, capfd):
    """
    Test : Generic connection modified with zone
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert "connection.zone" in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GENERIC_ZONE, indirect=["patch_ansible_module"])
def test_generic_connection_zone_unchanged(mocked_generic_connection_zone_unchanged, capfd):
    """
    Test : Generic connection with zone unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GENERIC_ZONE_ONLY, indirect=["patch_ansible_module"])
def test_generic_connection_modify_zone_only(mocked_generic_connection_modify, capfd):
    """
    Test : Generic connection modified with zone only
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert "connection.zone" in args[0]
    assert "ipv4.addresses" not in args[0]
    assert "ipv4.gateway" not in args[0]
    assert "ipv6.addresses" not in args[0]
    assert "ipv6.gateway" not in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_CONNECTION, indirect=["patch_ansible_module"])
def test_zone_none(mocked_connection_exists, capfd):
    """
    Test if zone param is None
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_BRIDGE, indirect=["patch_ansible_module"])
def test_create_bridge(mocked_generic_connection_create, capfd):
    """
    Test if Bridge created
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "bridge"
    assert args[0][5] == "con-name"
    assert args[0][6] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in [
        "ipv4.addresses",
        "10.10.10.10/24",
        "ipv4.gateway",
        "10.10.10.1",
        "bridge.max-age",
        "100",
        "bridge.stp",
        "yes",
    ]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_BRIDGE, indirect=["patch_ansible_module"])
def test_mod_bridge(mocked_generic_connection_modify, capfd):
    """
    Test if Bridge modified
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1

    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "modify"
    assert args[0][3] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in [
        "ipv4.addresses",
        "10.10.10.10/24",
        "ipv4.gateway",
        "10.10.10.1",
        "bridge.max-age",
        "100",
        "bridge.stp",
        "yes",
    ]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_BRIDGE, indirect=["patch_ansible_module"])
def test_bridge_connection_unchanged(mocked_bridge_connection_unchanged, capfd):
    """
    Test : Bridge connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_BRIDGE_SLAVE, indirect=["patch_ansible_module"])
def test_create_bridge_slave(mocked_generic_connection_create, capfd):
    """
    Test if Bridge_slave created
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "bridge-slave"
    assert args[0][5] == "con-name"
    assert args[0][6] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in ["bridge-port.path-cost", "100"]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_BRIDGE_SLAVE, indirect=["patch_ansible_module"])
def test_mod_bridge_slave(mocked_generic_connection_modify, capfd):
    """
    Test if Bridge_slave modified
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "modify"
    assert args[0][3] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in ["bridge-port.path-cost", "100"]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_BRIDGE_SLAVE, indirect=["patch_ansible_module"])
def test_bridge_slave_unchanged(mocked_bridge_slave_unchanged, capfd):
    """
    Test : Bridge-slave connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_TEAM, indirect=["patch_ansible_module"])
def test_team_connection_create(mocked_generic_connection_create, capfd):
    """
    Test : Team connection created
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "team"
    assert args[0][5] == "con-name"
    assert args[0][6] == "non_existent_nw_device"

    for param in ["connection.autoconnect", "connection.interface-name", "team0_non_existant"]:
        assert param in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_TEAM, indirect=["patch_ansible_module"])
def test_team_connection_unchanged(mocked_team_connection_unchanged, capfd):
    """
    Test : Team connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_TEAM_HWADDR_POLICY_FAILS, indirect=["patch_ansible_module"])
def test_team_connection_create_hwaddr_policy_fails(mocked_generic_connection_create, capfd):
    """
    Test : Team connection created
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert results.get("failed")
    assert results["msg"] == "Runner-hwaddr-policy is only allowed for runner activebackup"


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_TEAM_RUNNER_FAST_RATE, indirect=["patch_ansible_module"])
def test_team_runner_fast_rate_connection_create(mocked_generic_connection_create, capfd):
    """
    Test : Team connection created with runner_fast_rate parameter
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "team"
    assert args[0][5] == "con-name"
    assert args[0][6] == "non_existent_nw_device"

    for param in [
        "connection.autoconnect",
        "connection.interface-name",
        "team0_non_existant",
        "team.runner",
        "lacp",
        "team.runner-fast-rate",
        "yes",
    ]:
        assert param in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_TEAM_RUNNER_FAST_RATE, indirect=["patch_ansible_module"])
def test_team_runner_fast_rate_connection_unchanged(mocked_team_runner_fast_rate_connection_unchanged, capfd):
    """
    Test : Team connection unchanged with runner_fast_rate parameter
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_TEAM_RUNNER_FAST_RATE_FAILS, indirect=["patch_ansible_module"]
)
def test_team_connection_create_runner_fast_rate_fails(mocked_generic_connection_create, capfd):
    """
    Test : Team connection with runner_fast_rate enabled
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert results.get("failed")
    assert results["msg"] == "runner-fast-rate is only allowed for runner lacp"


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_TEAM_SLAVE, indirect=["patch_ansible_module"])
def test_create_team_slave(mocked_generic_connection_create, capfd):
    """
    Test if Team_slave created
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "team-slave"
    assert args[0][5] == "con-name"
    assert args[0][6] == "non_existent_nw_slaved_device"

    for param in [
        "connection.autoconnect",
        "connection.interface-name",
        "connection.master",
        "team0_non_existant",
        "connection.slave-type",
    ]:
        assert param in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_TEAM_SLAVE, indirect=["patch_ansible_module"])
def test_team_slave_connection_unchanged(mocked_team_slave_connection_unchanged, capfd):
    """
    Test : Team slave connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_VLAN, indirect=["patch_ansible_module"])
def test_create_vlan_con(mocked_generic_connection_create, capfd):
    """
    Test if VLAN created
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "vlan"
    assert args[0][5] == "con-name"
    assert args[0][6] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in ["ipv4.addresses", "10.10.10.10/24", "ipv4.gateway", "10.10.10.1", "vlan.id", "10"]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_VLAN, indirect=["patch_ansible_module"])
def test_mod_vlan_conn(mocked_generic_connection_modify, capfd):
    """
    Test if VLAN modified
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "modify"
    assert args[0][3] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in ["ipv4.addresses", "10.10.10.10/24", "ipv4.gateway", "10.10.10.1", "vlan.id", "10"]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_VLAN, indirect=["patch_ansible_module"])
def test_vlan_connection_unchanged(mocked_vlan_connection_unchanged, capfd):
    """
    Test : VLAN connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_VXLAN, indirect=["patch_ansible_module"])
def test_create_vxlan(mocked_generic_connection_create, capfd):
    """
    Test if vxlan created
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "vxlan"
    assert args[0][5] == "con-name"
    assert args[0][6] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in [
        "connection.interface-name",
        "vxlan-existent_nw_device",
        "vxlan.local",
        "192.168.225.5",
        "vxlan.remote",
        "192.168.225.6",
        "vxlan.id",
        "11",
    ]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_VXLAN, indirect=["patch_ansible_module"])
def test_vxlan_mod(mocked_generic_connection_modify, capfd):
    """
    Test if vxlan modified
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "modify"
    assert args[0][3] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in ["vxlan.local", "192.168.225.5", "vxlan.remote", "192.168.225.6", "vxlan.id", "11"]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_VXLAN, indirect=["patch_ansible_module"])
def test_vxlan_connection_unchanged(mocked_vxlan_connection_unchanged, capfd):
    """
    Test : VxLAN connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_VXLAN_MULTICAST, indirect=["patch_ansible_module"])
def test_create_vxlan_multicast(mocked_generic_connection_create, capfd):
    """
    Test if vxlan with multicast and parent device created
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "vxlan"
    assert args[0][5] == "con-name"
    assert args[0][6] == "vxlan_multicast_test"

    args_text = list(map(to_text, args[0]))
    for param in [
        "connection.interface-name",
        "vxlan-device",
        "vxlan.local",
        "192.168.1.2",
        "vxlan.remote",
        "239.192.0.17",
        "vxlan.id",
        "17",
        "vxlan.parent",
        "eth1",
        "connection.slave-type",
        "bridge",
        "connection.master",
        "br0",
    ]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_IPIP, indirect=["patch_ansible_module"])
def test_create_ipip(mocked_generic_connection_create, capfd):
    """
    Test if ipip created
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "ip-tunnel"
    assert args[0][5] == "con-name"
    assert args[0][6] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in [
        "connection.interface-name",
        "ipip-existent_nw_device",
        "ip-tunnel.local",
        "192.168.225.5",
        "ip-tunnel.mode",
        "ipip",
        "ip-tunnel.parent",
        "non_existent_ipip_device",
        "ip-tunnel.remote",
        "192.168.225.6",
    ]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_IPIP, indirect=["patch_ansible_module"])
def test_ipip_mod(mocked_generic_connection_modify, capfd):
    """
    Test if ipip modified
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "modify"
    assert args[0][3] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in ["ip-tunnel.local", "192.168.225.5", "ip-tunnel.remote", "192.168.225.6"]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_IPIP, indirect=["patch_ansible_module"])
def test_ipip_connection_unchanged(mocked_ipip_connection_unchanged, capfd):
    """
    Test : IPIP connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_SIT, indirect=["patch_ansible_module"])
def test_create_sit(mocked_generic_connection_create, capfd):
    """
    Test if sit created
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "ip-tunnel"
    assert args[0][5] == "con-name"
    assert args[0][6] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in [
        "connection.interface-name",
        "sit-existent_nw_device",
        "ip-tunnel.local",
        "192.168.225.5",
        "ip-tunnel.mode",
        "sit",
        "ip-tunnel.parent",
        "non_existent_sit_device",
        "ip-tunnel.remote",
        "192.168.225.6",
    ]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_SIT, indirect=["patch_ansible_module"])
def test_sit_mod(mocked_generic_connection_modify, capfd):
    """
    Test if sit modified
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "modify"
    assert args[0][3] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in ["ip-tunnel.local", "192.168.225.5", "ip-tunnel.remote", "192.168.225.6"]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_SIT, indirect=["patch_ansible_module"])
def test_sit_connection_unchanged(mocked_sit_connection_unchanged, capfd):
    """
    Test : SIT connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_ETHERNET_DHCP, indirect=["patch_ansible_module"])
def test_eth_dhcp_client_id_con_create(mocked_generic_connection_create, capfd):
    """
    Test : Ethernet connection created with DHCP_CLIENT_ID
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert "ipv4.dhcp-client-id" in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GRE, indirect=["patch_ansible_module"])
def test_create_gre(mocked_generic_connection_create, capfd):
    """
    Test if gre created
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "ip-tunnel"
    assert args[0][5] == "con-name"
    assert args[0][6] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in [
        "connection.interface-name",
        "gre-existent_nw_device",
        "ip-tunnel.local",
        "192.168.225.5",
        "ip-tunnel.mode",
        "gre",
        "ip-tunnel.parent",
        "non_existent_gre_device",
        "ip-tunnel.remote",
        "192.168.225.6",
        "ip-tunnel.input-key",
        "1",
        "ip-tunnel.output-key",
        "2",
    ]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GRE, indirect=["patch_ansible_module"])
def test_gre_mod(mocked_generic_connection_modify, capfd):
    """
    Test if gre modified
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "modify"
    assert args[0][3] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in ["ip-tunnel.local", "192.168.225.5", "ip-tunnel.remote", "192.168.225.6"]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GRE, indirect=["patch_ansible_module"])
def test_gre_connection_unchanged(mocked_gre_connection_unchanged, capfd):
    """
    Test : GRE connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_ETHERNET_DHCP, indirect=["patch_ansible_module"])
def test_ethernet_connection_dhcp_unchanged(mocked_ethernet_connection_dhcp_unchanged, capfd):
    """
    Test : Ethernet connection with DHCP_CLIENT_ID unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_ETHERNET_STATIC, indirect=["patch_ansible_module"])
def test_modify_ethernet_dhcp_to_static(mocked_ethernet_connection_dhcp_to_static, capfd):
    """
    Test : Modify ethernet connection from DHCP to static
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 2
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[1]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "modify"
    assert args[0][3] == "non_existent_nw_device"

    for param in ["ipv4.method", "ipv4.gateway", "ipv4.addresses"]:
        assert param in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_ETHERNET_STATIC, indirect=["patch_ansible_module"])
def test_create_ethernet_static(mocked_generic_connection_create, capfd):
    """
    Test : Create ethernet connection with static IP configuration
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 2
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[0]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "ethernet"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))
    for param in [
        "connection.interface-name",
        "ethernet_non_existant",
        "ipv4.addresses",
        "10.10.10.10/24",
        "ipv4.gateway",
        "10.10.10.1",
        "ipv4.dns",
        "1.1.1.1,8.8.8.8",
    ]:
        assert param in add_args_text

    up_args, up_kw = arg_list[1]
    assert up_args[0][0] == "/usr/bin/nmcli"
    assert up_args[0][1] == "con"
    assert up_args[0][2] == "up"
    assert up_args[0][3] == "non_existent_nw_device"

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_ETHERNET_STATIC, indirect=["patch_ansible_module"])
def test_ethernet_connection_static_unchanged(mocked_ethernet_connection_static_unchanged, capfd):
    """
    Test : Ethernet connection with static IP configuration unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_ETHERNET_MOD_IPV4_INT_WITH_ROUTE_AND_METRIC, indirect=["patch_ansible_module"]
)
def test_ethernet_connection_static_ipv4_address_static_route_with_metric_modify(
    mocked_ethernet_connection_with_ipv4_static_address_static_route_metric_modify, capfd
):
    """
    Test : Modify ethernet connection with static IPv4 address and static route
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[1]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "modify"
    assert add_args[0][3] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))

    for param in ["ipv4.routes", "192.168.200.0/24 192.168.1.1", "ipv4.route-metric", "10"]:
        assert param in add_args_text

    out, err = capfd.readouterr()
    results = json.loads(out)

    assert results.get("changed") is True
    assert not results.get("failed")


@pytest.mark.parametrize(
    "patch_ansible_module",
    TESTCASE_ETHERNET_MOD_IPV4_INT_WITH_ROUTE_AND_METRIC_CLEAR,
    indirect=["patch_ansible_module"],
)
def test_ethernet_connection_static_ipv4_address_static_route_with_metric_clear(
    mocked_ethernet_connection_with_ipv4_static_address_static_route_metric_clear, capfd
):
    """
    Test : Modify ethernet connection with static IPv4 address and static route
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[1]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "modify"
    assert add_args[0][3] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))

    for param in ["ipv4.routes", ""]:
        assert param in add_args_text

    out, err = capfd.readouterr()
    results = json.loads(out)

    assert "ipv4.routes" in results["diff"]["before"]
    assert "ipv4.routes" in results["diff"]["after"]

    assert results.get("changed") is True
    assert not results.get("failed")


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_ROUTE, indirect=["patch_ansible_module"]
)
def test_ethernet_connection_static_ipv6_address_static_route_create(
    mocked_ethernet_connection_with_ipv6_static_address_static_route_create, capfd
):
    """
    Test : Create ethernet connection with static IPv6 address and static route
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[0]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "ethernet"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))

    for param in [
        "connection.interface-name",
        "ethernet_non_existant",
        "con-name",
        "non_existent_nw_device",
        "ipv6.addresses",
        "2001:beef:cafe:10::1/64",
        "ipv6.method",
        "manual",
        "ipv6.routes",
        "fd2e:446f:d85d:5::/64 2001:beef:cafe:10::2",
    ]:
        assert param in add_args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_ETHERNET_MOD_IPV6_INT_WITH_ROUTE_AND_METRIC, indirect=["patch_ansible_module"]
)
def test_ethernet_connection_static_ipv6_address_static_route_metric_modify(
    mocked_ethernet_connection_with_ipv6_static_address_static_route_metric_modify, capfd
):
    """
    Test : Modify ethernet connection with static IPv6 address and static route
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[1]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "modify"
    assert add_args[0][3] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))

    for param in ["ipv6.routes", "fd2e:446f:d85d:5::/64 2001:beef:cafe:10::2", "ipv6.route-metric", "10"]:
        assert param in add_args_text

    out, err = capfd.readouterr()
    results = json.loads(out)

    assert results.get("changed") is True
    assert not results.get("failed")


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_MULTIPLE_ROUTES, indirect=["patch_ansible_module"]
)
def test_ethernet_connection_static_ipv6_address_multiple_static_routes_with_metric_create(
    mocked_ethernet_connection_with_ipv6_static_address_multiple_static_routes_with_metric_create, capfd
):
    """
    Test : Create ethernet connection with static IPv6 address and multiple static routes
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[0]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "ethernet"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))

    for param in [
        "connection.interface-name",
        "ethernet_non_existant",
        "con-name",
        "non_existent_nw_device",
        "ipv6.addresses",
        "2001:beef:cafe:10::1/64",
        "ipv6.method",
        "manual",
        "ipv6.routes",
        "fd2e:446f:d85d:5::/64 2001:beef:cafe:10::2,fd2e:8890:abcd:25::/64 2001:beef:cafe:10::5",
    ]:
        assert param in add_args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_ETHERNET_ADD_SRIOV_VFS, indirect=["patch_ansible_module"])
def test_ethernet_connection_sriov_vfs_create(mocked_ethernet_connection_with_sriov_vfs_create, capfd):
    """
    Test : Create ethernet connection with SR-IOV VFs
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[0]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "ethernet"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))

    for param in [
        "connection.interface-name",
        "ethernet_non_existant",
        "con-name",
        "non_existent_nw_device",
        "sriov.total-vfs",
        "16",
        "sriov.vfs",
        "0 spoof-check=true vlans=100",
    ]:
        assert param in add_args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_ROUTE_AND_METRIC, indirect=["patch_ansible_module"]
)
def test_ethernet_connection_static_ipv6_address_static_route_with_metric_create(
    mocked_ethernet_connection_with_ipv6_static_address_static_route_with_metric_create, capfd
):
    """
    Test : Create ethernet connection with static IPv6 address and static route with metric
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[0]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "ethernet"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))

    for param in [
        "connection.interface-name",
        "ethernet_non_existant",
        "con-name",
        "non_existent_nw_device",
        "ipv6.addresses",
        "2001:beef:cafe:10::1/64",
        "ipv6.method",
        "manual",
        "ipv6.routes",
        "fd2e:446f:d85d:5::/64 2001:beef:cafe:10::2",
        "ipv6.route-metric",
        "5",
    ]:
        assert param in add_args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize(
    "patch_ansible_module",
    TESTCASE_ETHERNET_ADD_IPV6_INT_WITH_MULTIPLE_ROUTES_AND_METRIC,
    indirect=["patch_ansible_module"],
)
def test_ethernet_connection_static_ipv6_address_static_route_create_2(
    mocked_ethernet_connection_with_ipv6_static_address_static_route_create, capfd
):
    """
    Test : Create ethernet connection with static IPv6 address and multiple static routes with metric
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[0]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "ethernet"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))

    for param in [
        "connection.interface-name",
        "ethernet_non_existant",
        "con-name",
        "non_existent_nw_device",
        "ipv6.addresses",
        "2001:beef:cafe:10::1/64",
        "ipv6.method",
        "manual",
        "ipv6.routes",
        "fd2e:446f:d85d:5::/64 2001:beef:cafe:10::2,fd2e:8890:abcd:25::/64 2001:beef:cafe:10::5",
        "ipv6.route-metric",
        "5",
    ]:
        assert param in add_args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_WIRELESS, indirect=["patch_ansible_module"])
def test_create_wireless(mocked_wireless_create, capfd):
    """
    Test : Create wireless connection
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 2
    arg_list = nmcli.Nmcli.execute_command.call_args_list

    get_available_options_args, get_available_options_kw = arg_list[0]
    assert get_available_options_args[0][0] == "/usr/bin/nmcli"
    assert get_available_options_args[0][1] == "con"
    assert get_available_options_args[0][2] == "edit"
    assert get_available_options_args[0][3] == "type"
    assert get_available_options_args[0][4] == "wifi"

    get_available_options_data = get_available_options_kw["data"].split()
    for param in ["print", "802-11-wireless", "quit", "yes"]:
        assert param in get_available_options_data

    add_args, add_kw = arg_list[1]
    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "wifi"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))
    for param in [
        "connection.interface-name",
        "wireless_non_existant",
        "ipv4.addresses",
        "10.10.10.10/24",
        "802-11-wireless.ssid",
        "Brittany",
        "802-11-wireless.mode",
        "ap",
        "802-11-wireless.hidden",
        "yes",
    ]:
        assert param in add_args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_SECURE_WIRELESS, indirect=["patch_ansible_module"])
def test_create_secure_wireless(mocked_secure_wireless_create, capfd):
    """
    Test : Create secure wireless connection
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 3
    arg_list = nmcli.Nmcli.execute_command.call_args_list

    get_available_options_args, get_available_options_kw = arg_list[0]
    assert get_available_options_args[0][0] == "/usr/bin/nmcli"
    assert get_available_options_args[0][1] == "con"
    assert get_available_options_args[0][2] == "edit"
    assert get_available_options_args[0][3] == "type"
    assert get_available_options_args[0][4] == "wifi"

    get_available_options_data = get_available_options_kw["data"].split()
    for param in ["print", "802-11-wireless-security", "quit", "yes"]:
        assert param in get_available_options_data

    add_args, add_kw = arg_list[1]
    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "wifi"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))
    for param in [
        "connection.interface-name",
        "wireless_non_existant",
        "ipv4.addresses",
        "10.10.10.10/24",
        "802-11-wireless.ssid",
        "Brittany",
        "802-11-wireless-security.key-mgmt",
        "wpa-psk",
    ]:
        assert param in add_args_text

    edit_args, edit_kw = arg_list[2]
    assert edit_args[0][0] == "/usr/bin/nmcli"
    assert edit_args[0][1] == "con"
    assert edit_args[0][2] == "edit"
    assert edit_args[0][3] == "non_existent_nw_device"

    edit_kw_data = edit_kw["data"].split()
    for param in ["802-11-wireless-security.psk", "VERY_SECURE_PASSWORD", "save", "quit"]:
        assert param in edit_kw_data

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_SECURE_WIRELESS, indirect=["patch_ansible_module"])
def test_create_secure_wireless_failure(mocked_secure_wireless_create_failure, capfd):
    """
    Test : Create secure wireless connection w/failure
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 2
    arg_list = nmcli.Nmcli.execute_command.call_args_list

    get_available_options_args, get_available_options_kw = arg_list[0]
    assert get_available_options_args[0][0] == "/usr/bin/nmcli"
    assert get_available_options_args[0][1] == "con"
    assert get_available_options_args[0][2] == "edit"
    assert get_available_options_args[0][3] == "type"
    assert get_available_options_args[0][4] == "wifi"

    get_available_options_data = get_available_options_kw["data"].split()
    for param in ["print", "802-11-wireless-security", "quit", "yes"]:
        assert param in get_available_options_data

    add_args, add_kw = arg_list[1]
    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "wifi"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))
    for param in [
        "connection.interface-name",
        "wireless_non_existant",
        "ipv4.addresses",
        "10.10.10.10/24",
        "802-11-wireless.ssid",
        "Brittany",
        "802-11-wireless-security.key-mgmt",
        "wpa-psk",
    ]:
        assert param in add_args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert results.get("failed")
    assert "changed" not in results


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_SECURE_WIRELESS, indirect=["patch_ansible_module"])
def test_modify_secure_wireless(mocked_secure_wireless_modify, capfd):
    """
    Test : Modify secure wireless connection
    """

    with pytest.raises(SystemExit):
        nmcli.main()
    assert nmcli.Nmcli.execute_command.call_count == 4
    arg_list = nmcli.Nmcli.execute_command.call_args_list

    get_available_options_args, get_available_options_kw = arg_list[0]
    assert get_available_options_args[0][0] == "/usr/bin/nmcli"
    assert get_available_options_args[0][1] == "con"
    assert get_available_options_args[0][2] == "edit"
    assert get_available_options_args[0][3] == "type"
    assert get_available_options_args[0][4] == "wifi"

    get_available_options_data = get_available_options_kw["data"].split()
    for param in ["print", "802-11-wireless-security", "quit", "yes"]:
        assert param in get_available_options_data

    show_args, show_kw = arg_list[1]
    assert show_args[0][0] == "/usr/bin/nmcli"
    assert show_args[0][1] == "--show-secrets"
    assert show_args[0][2] == "con"
    assert show_args[0][3] == "show"
    assert show_args[0][4] == "non_existent_nw_device"

    add_args, add_kw = arg_list[2]
    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "modify"
    assert add_args[0][3] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))
    for param in [
        "connection.interface-name",
        "wireless_non_existant",
        "ipv4.addresses",
        "10.10.10.10/24",
        "802-11-wireless.ssid",
        "Brittany",
        "802-11-wireless-security.key-mgmt",
        "wpa-psk",
    ]:
        assert param in add_args_text

    edit_args, edit_kw = arg_list[3]
    assert edit_args[0][0] == "/usr/bin/nmcli"
    assert edit_args[0][1] == "con"
    assert edit_args[0][2] == "edit"
    assert edit_args[0][3] == "non_existent_nw_device"

    edit_kw_data = edit_kw["data"].split()
    for param in ["802-11-wireless-security.psk", "VERY_SECURE_PASSWORD", "save", "quit"]:
        assert param in edit_kw_data

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_SECURE_WIRELESS, indirect=["patch_ansible_module"])
def test_modify_secure_wireless_failure(mocked_secure_wireless_modify_failure, capfd):
    """
    Test : Modify secure wireless connection w/failure
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 3
    arg_list = nmcli.Nmcli.execute_command.call_args_list

    get_available_options_args, get_available_options_kw = arg_list[0]
    assert get_available_options_args[0][0] == "/usr/bin/nmcli"
    assert get_available_options_args[0][1] == "con"
    assert get_available_options_args[0][2] == "edit"
    assert get_available_options_args[0][3] == "type"
    assert get_available_options_args[0][4] == "wifi"

    get_available_options_data = get_available_options_kw["data"].split()
    for param in ["print", "802-11-wireless-security", "quit", "yes"]:
        assert param in get_available_options_data

    show_args, show_kw = arg_list[1]
    assert show_args[0][0] == "/usr/bin/nmcli"
    assert show_args[0][1] == "--show-secrets"
    assert show_args[0][2] == "con"
    assert show_args[0][3] == "show"
    assert show_args[0][4] == "non_existent_nw_device"

    add_args, add_kw = arg_list[2]
    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "modify"
    assert add_args[0][3] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))
    for param in [
        "connection.interface-name",
        "wireless_non_existant",
        "ipv4.addresses",
        "10.10.10.10/24",
        "802-11-wireless.ssid",
        "Brittany",
        "802-11-wireless-security.key-mgmt",
        "wpa-psk",
    ]:
        assert param in add_args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert results.get("failed")
    assert "changed" not in results


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_DUMMY_STATIC, indirect=["patch_ansible_module"])
def test_create_dummy_static(mocked_generic_connection_create, capfd):
    """
    Test : Create dummy connection with static IP configuration
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 2
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[0]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "dummy"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))
    for param in [
        "connection.interface-name",
        "dummy_non_existant",
        "ipv4.addresses",
        "10.10.10.10/24",
        "ipv4.gateway",
        "10.10.10.1",
        "ipv4.dns",
        "1.1.1.1,8.8.8.8",
        "ipv6.addresses",
        "2001:db8::1/128",
    ]:
        assert param in add_args_text

    up_args, up_kw = arg_list[1]
    assert up_args[0][0] == "/usr/bin/nmcli"
    assert up_args[0][1] == "con"
    assert up_args[0][2] == "up"
    assert up_args[0][3] == "non_existent_nw_device"

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_DUMMY_STATIC, indirect=["patch_ansible_module"])
def test_dummy_connection_static_unchanged(mocked_dummy_connection_static_unchanged, capfd):
    """
    Test : Dummy connection with static IP configuration unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_DUMMY_STATIC, indirect=["patch_ansible_module"])
def test_dummy_connection_static_without_mtu_unchanged(mocked_dummy_connection_static_without_mtu_unchanged, capfd):
    """
    Test : Dummy connection with static IP configuration and no mtu set unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_DUMMY_STATIC, indirect=["patch_ansible_module"])
def test_dummy_connection_static_with_custom_mtu_modify(mocked_dummy_connection_static_with_custom_mtu_modify, capfd):
    """
    Test : Dummy connection with static IP configuration and no mtu set modify
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 2

    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[1]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "modify"
    assert args[0][3] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in ["802-3-ethernet.mtu", "0"]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GSM, indirect=["patch_ansible_module"])
def test_create_gsm(mocked_generic_connection_create, capfd):
    """
    Test if gsm created
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "gsm"
    assert args[0][5] == "con-name"
    assert args[0][6] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in [
        "connection.interface-name",
        "gsm_non_existant",
        "gsm.apn",
        "internet.telekom",
        "gsm.username",
        "t-mobile",
        "gsm.password",
        "tm",
        "gsm.pin",
        "1234",
    ]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GSM, indirect=["patch_ansible_module"])
def test_gsm_mod(mocked_generic_connection_modify, capfd):
    """
    Test if gsm modified
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "modify"
    assert args[0][3] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in ["gsm.username", "t-mobile", "gsm.password", "tm"]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GSM, indirect=["patch_ansible_module"])
def test_gsm_connection_unchanged(mocked_gsm_connection_unchanged, capfd):
    """
    Test if gsm connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_ETHERNET_STATIC_MULTIPLE_IP4_ADDRESSES, indirect=["patch_ansible_module"]
)
def test_create_ethernet_with_multiple_ip4_addresses_static(mocked_generic_connection_create, capfd):
    """
    Test : Create ethernet connection with static IP configuration
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 2
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[0]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "ethernet"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))
    for param in [
        "connection.interface-name",
        "ethernet_non_existant",
        "ipv4.addresses",
        "10.10.10.10/32,10.10.20.10/32",
        "ipv4.gateway",
        "10.10.10.1",
        "ipv4.dns",
        "1.1.1.1,8.8.8.8",
    ]:
        assert param in add_args_text

    up_args, up_kw = arg_list[1]
    assert up_args[0][0] == "/usr/bin/nmcli"
    assert up_args[0][1] == "con"
    assert up_args[0][2] == "up"
    assert up_args[0][3] == "non_existent_nw_device"

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_ETHERNET_STATIC_MULTIPLE_IP6_ADDRESSES, indirect=["patch_ansible_module"]
)
def test_create_ethernet_with_multiple_ip6_addresses_static(mocked_generic_connection_create, capfd):
    """
    Test : Create ethernet connection with multiple IPv6 addresses configuration
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 2
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[0]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "ethernet"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))
    for param in [
        "connection.interface-name",
        "ethernet_non_existant",
        "ipv6.addresses",
        "2001:db8::cafe/128,2002:db8::cafe/128",
        "ipv6.gateway",
        "2001:db8::cafa",
        "ipv6.dns",
        "2001:4860:4860::8888,2001:4860:4860::8844",
    ]:
        assert param in add_args_text

    up_args, up_kw = arg_list[1]
    assert up_args[0][0] == "/usr/bin/nmcli"
    assert up_args[0][1] == "con"
    assert up_args[0][2] == "up"
    assert up_args[0][3] == "non_existent_nw_device"

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_ETHERNET_STATIC_MULTIPLE_IP4_ADDRESSES, indirect=["patch_ansible_module"]
)
def test_ethernet_connection_static_with_multiple_ip4_addresses_unchanged(
    mocked_ethernet_connection_static_multiple_ip4_addresses_unchanged, capfd
):
    """
    Test : Ethernet connection with static IP configuration unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_ETHERNET_STATIC_MULTIPLE_IP6_ADDRESSES, indirect=["patch_ansible_module"]
)
def test_ethernet_connection_static_with_multiple_ip6_addresses_unchanged(
    mocked_ethernet_connection_static_multiple_ip6_addresses_unchanged, capfd
):
    """
    Test : Ethernet connection with multiple IPv6 addresses configuration unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_ETHERNET_STATIC_MULTIPLE_IP4_ADDRESSES, indirect=["patch_ansible_module"]
)
def test_add_second_ip4_address_to_ethernet_connection(mocked_ethernet_connection_static_modify, capfd):
    """
    Test : Modify ethernet connection from DHCP to static
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 2
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[1]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "modify"
    assert args[0][3] == "non_existent_nw_device"

    for param in ["ipv4.addresses", "10.10.10.10/32,10.10.20.10/32"]:
        assert param in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_ETHERNET_STATIC_IP6_PRIVACY_AND_ADDR_GEN_MODE, indirect=["patch_ansible_module"]
)
def test_create_ethernet_addr_gen_mode_and_ip6_privacy_static(mocked_generic_connection_create, capfd):
    """
    Test : Create ethernet connection with static IP configuration
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 2
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[0]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "ethernet"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))
    for param in [
        "connection.interface-name",
        "ethernet_non_existant",
        "ipv6.addresses",
        "2001:db8::cafe/128",
        "ipv6.gateway",
        "2001:db8::cafa",
        "ipv6.dns",
        "2001:4860:4860::8888",
        "ipv6.ip6-privacy",
        "prefer-public-addr",
        "ipv6.addr-gen-mode",
        "eui64",
    ]:
        assert param in add_args_text

    up_args, up_kw = arg_list[1]
    assert up_args[0][0] == "/usr/bin/nmcli"
    assert up_args[0][1] == "con"
    assert up_args[0][2] == "up"
    assert up_args[0][3] == "non_existent_nw_device"

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_ETHERNET_STATIC_IP6_PRIVACY_AND_ADDR_GEN_MODE, indirect=["patch_ansible_module"]
)
def test_ethernet_connection_static_with_multiple_ip4_addresses_unchanged_2(
    mocked_ethernet_connection_static_ip6_privacy_and_addr_gen_mode_unchange, capfd
):
    """
    Test : Ethernet connection with static IP configuration unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_WIREGUARD, indirect=["patch_ansible_module"])
def test_create_wireguard(mocked_generic_connection_create, capfd):
    """
    Test : Create wireguard connection with static IP configuration
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[0]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "wireguard"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))
    for param in [
        "connection.interface-name",
        "wg_non_existant",
        "ipv4.method",
        "manual",
        "ipv4.addresses",
        "10.10.10.10/24",
        "ipv6.method",
        "manual",
        "ipv6.addresses",
        "2001:db8::1/128",
        "wireguard.listen-port",
        "51820",
        "wireguard.private-key",
        "<hidden>",
    ]:
        assert param in add_args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_WIREGUARD, indirect=["patch_ansible_module"])
def test_wireguard_connection_unchanged(mocked_wireguard_connection_unchanged, capfd):
    """
    Test : Wireguard connection with static IP configuration unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_WIREGUARD, indirect=["patch_ansible_module"])
def test_wireguard_mod(mocked_generic_connection_modify, capfd):
    """
    Test : Modify wireguard connection
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "modify"
    assert args[0][3] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in ["wireguard.listen-port", "51820"]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_VPN_L2TP, indirect=["patch_ansible_module"])
def test_vpn_l2tp_connection_unchanged(mocked_vpn_l2tp_connection_unchanged, capfd):
    """
    Test : L2TP VPN connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_VPN_PPTP, indirect=["patch_ansible_module"])
def test_vpn_pptp_connection_unchanged(mocked_vpn_pptp_connection_unchanged, capfd):
    """
    Test : PPTP VPN connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_VPN_L2TP, indirect=["patch_ansible_module"])
def test_create_vpn_l2tp(mocked_generic_connection_create, capfd):
    """
    Test : Create L2TP VPN connection
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[0]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "vpn"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "vpn_l2tp"

    add_args_text = list(map(to_text, add_args[0]))

    for param in [
        "connection.autoconnect",
        "no",
        "connection.permissions",
        "brittany",
        "vpn.data",
        "vpn.service-type",
        "org.freedesktop.NetworkManager.l2tp",
    ]:
        assert param in add_args_text

    vpn_data_index = add_args_text.index("vpn.data") + 1
    args_vpn_data = add_args_text[vpn_data_index]
    for vpn_data in [
        "gateway=vpn.example.com",
        "password-flags=2",
        "user=brittany",
        "ipsec-enabled=true",
        "ipsec-psk=QnJpdHRhbnkxMjM=",
    ]:
        assert vpn_data in args_vpn_data

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_VPN_PPTP, indirect=["patch_ansible_module"])
def test_create_vpn_pptp(mocked_generic_connection_create, capfd):
    """
    Test : Create PPTP VPN connection
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[0]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "vpn"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "vpn_pptp"

    add_args_text = list(map(to_text, add_args[0]))

    for param in [
        "connection.autoconnect",
        "no",
        "connection.permissions",
        "brittany",
        "vpn.data",
        "vpn.service-type",
        "org.freedesktop.NetworkManager.pptp",
    ]:
        assert param in add_args_text

    vpn_data_index = add_args_text.index("vpn.data") + 1
    args_vpn_data = add_args_text[vpn_data_index]
    for vpn_data in ["password-flags=2", "gateway=vpn.example.com", "user=brittany"]:
        assert vpn_data in args_vpn_data

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_INFINIBAND_STATIC, indirect=["patch_ansible_module"])
def test_infiniband_connection_static_unchanged(mocked_infiniband_connection_static_unchanged, capfd):
    """
    Test : Infiniband connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_INFINIBAND_STATIC_MODIFY_TRANSPORT_MODE, indirect=["patch_ansible_module"]
)
def test_infiniband_connection_static_transport_mode_connected(
    mocked_infiniband_connection_static_transport_mode_connected_modify, capfd
):
    """
    Test : Modify Infiniband connection to use connected as transport_mode
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[1]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "modify"
    assert add_args[0][3] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))

    for param in ["infiniband.transport-mode", "connected"]:
        assert param in add_args_text

    out, err = capfd.readouterr()
    results = json.loads(out)

    assert results.get("changed") is True
    assert not results.get("failed")


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_GENERIC_DIFF_CHECK, indirect=["patch_ansible_module"])
def test_bond_connection_unchanged_2(mocked_generic_connection_diff_check, capfd):
    """
    Test : Bond connection unchanged
    """

    module = nmcli.create_module()

    nmcli_module = nmcli.Nmcli(module)

    changed, diff = nmcli_module.is_connection_changed()

    assert changed

    num_of_diff_params = 0
    for parameter, value in diff.get("before").items():
        if value != diff["after"][parameter]:
            num_of_diff_params += 1

    assert num_of_diff_params == 1


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_MACVLAN, indirect=["patch_ansible_module"])
def test_create_macvlan(mocked_generic_connection_create, capfd):
    """
    Test : Create macvlan connection with static IP configuration
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[0]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "macvlan"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "non_existent_nw_device"

    add_args_text = list(map(to_text, add_args[0]))
    for param in [
        "connection.interface-name",
        "macvlan_non_existant",
        "ipv4.method",
        "manual",
        "ipv4.addresses",
        "10.10.10.10/24",
        "ipv6.method",
        "manual",
        "ipv6.addresses",
        "2001:db8::1/128",
        "macvlan.mode",
        "2",
        "macvlan.parent",
        "non_existent_parent",
    ]:
        assert param in add_args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_MACVLAN, indirect=["patch_ansible_module"])
def test_macvlan_connection_unchanged(mocked_macvlan_connection_unchanged, capfd):
    """
    Test : Macvlan connection with static IP configuration unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_MACVLAN, indirect=["patch_ansible_module"])
def test_macvlan_mod(mocked_generic_connection_modify, capfd):
    """
    Test : Modify macvlan connection
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "modify"
    assert args[0][3] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in ["macvlan.mode", "2"]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


TESTCASE_SLAVE_TYPE_BRIDGE_CONNECTION = [
    {
        "type": "ethernet",
        "conn_name": "fake_conn",
        "ifname": "fake_eth0",
        "state": "present",
        "slave_type": "bridge",
        "master": "fake_br0",
        "_ansible_check_mode": False,
    }
]


TESTCASE_SLAVE_TYPE_BRIDGE_CONNECTION_SHOW_OUTPUT = """\
connection.id:                          fake_conn
connection.type:                        802-3-ethernet
connection.interface-name:              fake_eth0
connection.autoconnect:                 yes
connection.master:                      --
connection.slave-type:                  --
802-3-ethernet.mtu:                     auto
"""


TESTCASE_SLAVE_TYPE_BRIDGE_CONNECTION_UNCHANGED_SHOW_OUTPUT = """\
connection.id:                          fake_conn
connection.type:                        802-3-ethernet
connection.interface-name:              fake_eth0
connection.autoconnect:                 yes
connection.master:                      fake_br0
connection.slave-type:                  bridge
802-3-ethernet.mtu:                     auto
"""


@pytest.fixture
def mocked_slave_type_bridge_create(mocker):
    mocker_set(
        mocker,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_SLAVE_TYPE_BRIDGE_CONNECTION_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_SLAVE_TYPE_BRIDGE_CONNECTION, indirect=["patch_ansible_module"]
)
def test_create_slave_type_bridge(mocked_slave_type_bridge_create, capfd):
    """
    Test : slave for bridge created
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "ethernet"
    assert args[0][5] == "con-name"
    assert args[0][6] == "fake_conn"
    con_master_index = args[0].index("connection.master")
    slave_type_index = args[0].index("connection.slave-type")
    assert args[0][con_master_index + 1] == "fake_br0"
    assert args[0][slave_type_index + 1] == "bridge"

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.fixture
def mocked_create_slave_type_bridge_unchanged(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=(0, TESTCASE_SLAVE_TYPE_BRIDGE_CONNECTION_UNCHANGED_SHOW_OUTPUT, ""),
    )


@pytest.mark.parametrize(
    "patch_ansible_module", TESTCASE_SLAVE_TYPE_BRIDGE_CONNECTION, indirect=["patch_ansible_module"]
)
def test_slave_type_bridge_unchanged(mocked_create_slave_type_bridge_unchanged, capfd):
    """
    Test : Existent slave for bridge unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


TESTCASE_SLAVE_TYPE_BOND_CONNECTION = [
    {
        "type": "ethernet",
        "conn_name": "fake_conn",
        "ifname": "fake_eth0",
        "state": "present",
        "slave_type": "bond",
        "master": "fake_bond0",
        "_ansible_check_mode": False,
    }
]


TESTCASE_SLAVE_TYPE_BOND_CONNECTION_SHOW_OUTPUT = """\
connection.id:                          fake_conn
connection.type:                        802-3-ethernet
connection.interface-name:              fake_eth0
connection.autoconnect:                 yes
connection.master:                      --
connection.slave-type:                  --
802-3-ethernet.mtu:                     auto
"""


TESTCASE_SLAVE_TYPE_BOND_CONNECTION_UNCHANGED_SHOW_OUTPUT = """\
connection.id:                          fake_conn
connection.type:                        802-3-ethernet
connection.interface-name:              fake_eth0
connection.autoconnect:                 yes
connection.master:                      fake_bond0
connection.slave-type:                  bond
802-3-ethernet.mtu:                     auto
"""


@pytest.fixture
def mocked_slave_type_bond_create(mocker):
    mocker_set(
        mocker,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_SLAVE_TYPE_BOND_CONNECTION_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_SLAVE_TYPE_BOND_CONNECTION, indirect=["patch_ansible_module"])
def test_create_slave_type_bond(mocked_slave_type_bond_create, capfd):
    """
    Test : slave for bond created
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "ethernet"
    assert args[0][5] == "con-name"
    assert args[0][6] == "fake_conn"
    con_master_index = args[0].index("connection.master")
    slave_type_index = args[0].index("connection.slave-type")
    assert args[0][con_master_index + 1] == "fake_bond0"
    assert args[0][slave_type_index + 1] == "bond"

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.fixture
def mocked_create_slave_type_bond_unchanged(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=(0, TESTCASE_SLAVE_TYPE_BOND_CONNECTION_UNCHANGED_SHOW_OUTPUT, ""),
    )


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_SLAVE_TYPE_BOND_CONNECTION, indirect=["patch_ansible_module"])
def test_slave_type_bond_unchanged(mocked_create_slave_type_bond_unchanged, capfd):
    """
    Test : Existent slave for bridge unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


TESTCASE_SLAVE_TYPE_TEAM_CONNECTION = [
    {
        "type": "ethernet",
        "conn_name": "fake_conn",
        "ifname": "fake_eth0",
        "state": "present",
        "slave_type": "team",
        "master": "fake_team0",
        "_ansible_check_mode": False,
    }
]


TESTCASE_SLAVE_TYPE_TEAM_CONNECTION_SHOW_OUTPUT = """\
connection.id:                          fake_conn
connection.type:                        802-3-ethernet
connection.interface-name:              fake_eth0
connection.autoconnect:                 yes
connection.master:                      --
connection.slave-type:                  --
802-3-ethernet.mtu:                     auto
"""


TESTCASE_SLAVE_TYPE_TEAM_CONNECTION_UNCHANGED_SHOW_OUTPUT = """\
connection.id:                          fake_conn
connection.type:                        802-3-ethernet
connection.interface-name:              fake_eth0
connection.autoconnect:                 yes
connection.master:                      fake_team0
connection.slave-type:                  team
802-3-ethernet.mtu:                     auto
"""


@pytest.fixture
def mocked_slave_type_team_create(mocker):
    mocker_set(
        mocker,
        execute_return=None,
        execute_side_effect=(
            (0, TESTCASE_SLAVE_TYPE_TEAM_CONNECTION_SHOW_OUTPUT, ""),
            (0, "", ""),
        ),
    )


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_SLAVE_TYPE_TEAM_CONNECTION, indirect=["patch_ansible_module"])
def test_create_slave_type_team(mocked_slave_type_team_create, capfd):
    """
    Test : slave for bond created
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "ethernet"
    assert args[0][5] == "con-name"
    assert args[0][6] == "fake_conn"
    con_master_index = args[0].index("connection.master")
    slave_type_index = args[0].index("connection.slave-type")
    assert args[0][con_master_index + 1] == "fake_team0"
    assert args[0][slave_type_index + 1] == "team"

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.fixture
def mocked_create_slave_type_team_unchanged(mocker):
    mocker_set(
        mocker,
        connection_exists=True,
        execute_return=(0, TESTCASE_SLAVE_TYPE_TEAM_CONNECTION_UNCHANGED_SHOW_OUTPUT, ""),
    )


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_SLAVE_TYPE_TEAM_CONNECTION, indirect=["patch_ansible_module"])
def test_slave_type_team_unchanged(mocked_create_slave_type_team_unchanged, capfd):
    """
    Test : Existent slave for bridge unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_LOOPBACK, indirect=["patch_ansible_module"])
def test_create_loopback(mocked_generic_connection_create, capfd):
    """
    Test : Create loopback connection
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    add_args, add_kw = arg_list[0]

    assert add_args[0][0] == "/usr/bin/nmcli"
    assert add_args[0][1] == "con"
    assert add_args[0][2] == "add"
    assert add_args[0][3] == "type"
    assert add_args[0][4] == "loopback"
    assert add_args[0][5] == "con-name"
    assert add_args[0][6] == "lo"

    add_args_text = list(map(to_text, add_args[0]))
    for param in ["connection.interface-name", "lo", "ipv4.addresses", "127.0.0.1/8"]:
        assert param in add_args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_LOOPBACK, indirect=["patch_ansible_module"])
def test_unchanged_loopback(mocked_loopback_connection_unchanged, capfd):
    """
    Test : loopback connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_LOOPBACK_MODIFY, indirect=["patch_ansible_module"])
def test_add_second_ip4_address_to_loopback_connection(mocked_loopback_connection_modify, capfd):
    """
    Test : Modify loopback connection
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 2
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[1]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "modify"
    assert args[0][3] == "lo"

    for param in ["ipv4.addresses", "127.0.0.1/8,127.0.0.2/8"]:
        assert param in args[0]

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_VRF, indirect=["patch_ansible_module"])
def test_create_vrf_con(mocked_generic_connection_create, capfd):
    """
    Test if VRF created
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "add"
    assert args[0][3] == "type"
    assert args[0][4] == "vrf"
    assert args[0][5] == "con-name"
    assert args[0][6] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in ["ipv4.addresses", "10.10.10.10/24", "ipv4.gateway", "10.10.10.1", "table", "10"]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_VRF, indirect=["patch_ansible_module"])
def test_mod_vrf_conn(mocked_generic_connection_modify, capfd):
    """
    Test if VRF modified
    """

    with pytest.raises(SystemExit):
        nmcli.main()

    assert nmcli.Nmcli.execute_command.call_count == 1
    arg_list = nmcli.Nmcli.execute_command.call_args_list
    args, kwargs = arg_list[0]

    assert args[0][0] == "/usr/bin/nmcli"
    assert args[0][1] == "con"
    assert args[0][2] == "modify"
    assert args[0][3] == "non_existent_nw_device"

    args_text = list(map(to_text, args[0]))
    for param in ["ipv4.addresses", "10.10.10.10/24", "ipv4.gateway", "10.10.10.1", "table", "10"]:
        assert param in args_text

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert results["changed"]


@pytest.mark.parametrize("patch_ansible_module", TESTCASE_VRF, indirect=["patch_ansible_module"])
def test_vrf_connection_unchanged(mocked_vrf_connection_unchanged, capfd):
    """
    Test : VRF connection unchanged
    """
    with pytest.raises(SystemExit):
        nmcli.main()

    out, err = capfd.readouterr()
    results = json.loads(out)
    assert not results.get("failed")
    assert not results["changed"]
